package com.sms.manager;

import com.sms.exception.DataFileCorruptedException;
import com.sms.exception.SMSException;
import com.sms.model.Course;
import com.sms.model.Score;
import com.sms.model.Student;
import com.sms.service.*;

import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class MenuManager {
    private final StudentService studentService;
    private final CourseService courseService;
    private final ScoreService scoreService;
    private final ReportService reportService;
    private final Scanner scanner;

    public MenuManager(StudentService studentService, CourseService courseService,
                       ScoreService scoreService, ReportService reportService) {
        this.studentService = studentService;
        this.courseService = courseService;
        this.scoreService = scoreService;
        this.reportService = reportService;
        this.scanner = new Scanner(System.in);
    }

    // ============ 菜单显示方法 ============

    public void showMainMenu() {
        clearScreen();
        displayLogo();
        System.out.println("\n╔══════════════════════════════╗");
        System.out.println("║       主菜单                ║");
        System.out.println("╠══════════════════════════════╣");
        System.out.println("║ 1. 学生管理                 ║");
        System.out.println("║ 2. 课程管理                 ║");
        System.out.println("║ 3. 成绩管理                 ║");
        System.out.println("║ 4. 报表统计                 ║");
        System.out.println("║ 0. 退出系统                 ║");
        System.out.println("╚══════════════════════════════╝");
        System.out.print("请选择操作(0-4): ");
    }

    public void showStudentMenu() {
        clearScreen();
        System.out.println("\n╔══════════════════════════════╗");
        System.out.println("║       学生管理              ║");
        System.out.println("╠══════════════════════════════╣");
        System.out.println("║ 1. 添加学生                ║");
        System.out.println("║ 2. 删除学生                ║");
        System.out.println("║ 3. 查询学生                ║");
        System.out.println("║ 4. 所有学生列表            ║");
        System.out.println("║ 0. 返回主菜单              ║");
        System.out.println("╚══════════════════════════════╝");
        System.out.print("请选择操作(0-4): ");
    }

    public void showCourseMenu() {
        clearScreen();
        System.out.println("\n╔══════════════════════════════╗");
        System.out.println("║       课程管理              ║");
        System.out.println("╠══════════════════════════════╣");
        System.out.println("║ 1. 添加课程                ║");
        System.out.println("║ 2. 删除课程                ║");
        System.out.println("║ 3. 查询课程                ║");
        System.out.println("║ 4. 所有课程列表            ║");
        System.out.println("║ 0. 返回主菜单              ║");
        System.out.println("╚══════════════════════════════╝");
        System.out.print("请选择操作(0-4): ");
    }

    public void showScoreMenu() {
        clearScreen();
        System.out.println("\n╔══════════════════════════════╗");
        System.out.println("║       成绩管理              ║");
        System.out.println("╠══════════════════════════════╣");
        System.out.println("║ 1. 添加成绩                ║");
        System.out.println("║ 2. 修改成绩                ║");
        System.out.println("║ 3. 删除成绩                ║");
        System.out.println("║ 4. 查询成绩                ║");
        System.out.println("║ 0. 返回主菜单              ║");
        System.out.println("╚══════════════════════════════╝");
        System.out.print("请选择操作(0-4): ");
    }

    public void showReportMenu() {
        clearScreen();
        System.out.println("\n╔══════════════════════════════╗");
        System.out.println("║       报表统计              ║");
        System.out.println("╠══════════════════════════════╣");
        System.out.println("║ 1. 学生成绩报表            ║");
        System.out.println("║ 2. 班级成绩报表            ║");
        System.out.println("║ 3. 课程成绩报表            ║");
        System.out.println("║ 4. 系统概要报表            ║");
        System.out.println("║ 0. 返回主菜单              ║");
        System.out.println("╚══════════════════════════════╝");
        System.out.print("请选择操作(0-4): ");
    }

    // ============ 菜单处理方法 ============

    public void handleMainMenuChoice(int choice) throws SMSException, DataFileCorruptedException {
        switch (choice) {
            case 1:
                handleStudentMenu();
                break;
            case 2:
                handleCourseMenu();
                break;
            case 3:
                handleScoreMenu();
                break;
            case 4:
                handleReportMenu();
                break;
            case 0:
                System.out.println("感谢使用学生管理系统，再见！");
                System.exit(0);
            default:
                System.out.println("无效选择，请重新输入！");
                pause();
        }
    }

    private void handleStudentMenu() throws SMSException, DataFileCorruptedException {
        while (true) {
            showStudentMenu();
            int choice = readIntInput();
            switch (choice) {
                case 1:
                    addStudent();
                    break;
                case 2:
                    deleteStudent();
                    break;
                case 3:
                    queryStudent();
                    break;
                case 4:
                    listAllStudents();
                    break;
                case 0:
                    return;
                default:
                    System.out.println("无效选择，请重新输入！");
                    pause();
            }
        }
    }

    private void handleCourseMenu() throws SMSException, DataFileCorruptedException {
        while (true) {
            showCourseMenu();
            int choice = readIntInput();
            switch (choice) {
                case 1:
                    addCourse();
                    break;
                case 2:
                    deleteCourse();
                    break;
                case 3:
                    queryCourse();
                    break;
                case 4:
                    listAllCourses();
                    break;
                case 0:
                    return;
                default:
                    System.out.println("无效选择，请重新输入！");
                    pause();
            }
        }
    }

    private void handleScoreMenu() throws SMSException, DataFileCorruptedException {
        while (true) {
            showScoreMenu();
            int choice = readIntInput();
            switch (choice) {
                case 1:
                    addScore();
                    break;
                case 2:
                    updateScore();
                    break;
                case 3:
                    deleteScore();
                    break;
                case 4:
                    queryScore();
                    break;
                case 0:
                    return;
                default:
                    System.out.println("无效选择，请重新输入！");
                    pause();
            }
        }
    }

    private void handleReportMenu() throws SMSException, DataFileCorruptedException {
        while (true) {
            showReportMenu();
            int choice = readIntInput();
            switch (choice) {
                case 1:
                    generateStudentReport();
                    break;
                case 2:
                    generateClassReport();
                    break;
                case 3:
                    generateCourseReport();
                    break;
                case 4:
                    generateSystemSummary();
                    break;
                case 0:
                    return;
                default:
                    System.out.println("无效选择，请重新输入！");
                    pause();
            }
        }
    }

    // ============ 具体操作方法 ============

    // ============ 学生管理操作方法 ============

    private void addStudent() throws SMSException, DataFileCorruptedException {
        clearScreen();
        System.out.println("\n=== 添加学生 ===");

        System.out.print("学号: ");
        String id = scanner.nextLine();

        System.out.print("姓名: ");
        String name = scanner.nextLine();

        System.out.print("年龄: ");
        int age = readIntInput();

        System.out.print("性别(男/女): ");
        String gender = scanner.nextLine();

        System.out.print("班级: ");
        String className = scanner.nextLine();

        Student student = new Student();
        student.setId(id);
        student.setName(name);
        student.setAge(age);
        student.setGender(gender);
        student.setClassName(className);

        studentService.addStudent(student);
        System.out.println("\n学生添加成功！");
        pause();
    }

    private void deleteStudent() throws DataFileCorruptedException {
        clearScreen();
        System.out.println("\n=== 删除学生 ===");

        System.out.print("请输入要删除的学生学号: ");
        String id = scanner.nextLine();

        boolean success = studentService.deleteStudent(id);
        if (success) {
            System.out.println("学生删除成功!");
        } else {
            System.out.println("学生不存在，删除失败!");
        }
        pause();
    }

    private void queryStudent() throws DataFileCorruptedException {
        clearScreen();
        System.out.println("\n=== 查询学生 ===");

        System.out.print("请输入要查询的学生学号: ");
        String id = scanner.nextLine();

        Student student = studentService.getStudent(id);
        if (student != null) {
            System.out.println("\n学生信息:");
            System.out.println("学号: " + student.getId());
            System.out.println("姓名: " + student.getName());
            System.out.println("年龄: " + student.getAge());
            System.out.println("性别: " + student.getGender());
            System.out.println("班级: " + student.getClassName());
        } else {
            System.out.println("学生不存在!");
        }
        pause();
    }

    private void listAllStudents() throws DataFileCorruptedException {
        clearScreen();
        System.out.println("\n=== 所有学生列表 ===");

        List<Student> students = studentService.getAllStudents();

        if (students.isEmpty()) {
            System.out.println("没有学生记录");
            pause();
            return;
        }

        System.out.printf("%-10s %-10s %-5s %-5s %-10s%n",
                "学号", "姓名", "年龄", "性别", "班级");
        System.out.println("----------------------------------------");

        for (Student s : students) {
            System.out.printf("%-10s %-10s %-5d %-5s %-10s%n",
                    s.getId(), s.getName(), s.getAge(), s.getGender(), s.getClassName());
        }
        pause();
    }

    // ============ 课程管理操作方法 ============

    private void addCourse() throws SMSException, DataFileCorruptedException {
        clearScreen();
        System.out.println("\n=== 添加课程 ===");

        System.out.print("课程ID(格式如C001): ");
        String courseId = scanner.nextLine();

        System.out.print("课程名称: ");
        String courseName = scanner.nextLine();

        System.out.print("学分(0.5-10.0): ");
        double credit = scanner.nextDouble();

        Course course = new Course();
        course.setCourseId(courseId);
        course.setCourseName(courseName);
        course.setCredit(credit);

        courseService.addCourse(course);
        System.out.println("\n课程添加成功！");
        pause();
    }

    private void deleteCourse() throws DataFileCorruptedException {
        clearScreen();
        System.out.println("\n=== 删除课程 ===");

        System.out.print("请输入要删除的课程ID: ");
        String courseId = scanner.nextLine();

        boolean success = courseService.deleteCourse(courseId);
        if (success) {
            System.out.println("课程删除成功!");
        } else {
            System.out.println("课程不存在，删除失败!");
        }
        pause();
    }

    private void queryCourse() throws DataFileCorruptedException {
        clearScreen();
        System.out.println("\n=== 查询课程 ===");

        System.out.print("请输入要查询的课程ID: ");
        String courseId = scanner.nextLine();

        Course course = courseService.getCourse(courseId);
        if (course != null) {
            System.out.println("\n课程信息:");
            System.out.println("课程ID: " + course.getCourseId());
            System.out.println("课程名称: " + course.getCourseName());
            System.out.println("学分: " + course.getCredit());
        } else {
            System.out.println("课程不存在!");
        }
        pause();
    }

    private void listAllCourses() throws DataFileCorruptedException {
        clearScreen();
        System.out.println("\n=== 所有课程列表 ===");

        List<Course> courses = courseService.getAllCourses();

        if (courses.isEmpty()) {
            System.out.println("没有课程记录");
            pause();
            return;
        }

        System.out.printf("%-10s %-20s %-5s%n",
                "课程ID", "课程名称", "学分");
        System.out.println("----------------------------------");

        for (Course c : courses) {
            System.out.printf("%-10s %-20s %-5.1f%n",
                    c.getCourseId(), c.getCourseName(), c.getCredit());
        }
        pause();
    }

    // ============ 成绩管理操作方法 ============

    private void addScore() throws SMSException, DataFileCorruptedException {
        clearScreen();
        System.out.println("\n=== 添加成绩 ===");

        System.out.print("学生学号: ");
        String studentId = scanner.nextLine();

        System.out.print("课程ID: ");
        String courseId = scanner.nextLine();

        System.out.print("成绩(0-100): ");
        double scoreValue = scanner.nextDouble();

        System.out.print("考试日期(YYYY-MM-DD): ");
        String examDate = scanner.nextLine();

        Score score = new Score();
        score.setStudentId(studentId);
        score.setCourseId(courseId);
        score.setScore(scoreValue);
        score.setExamDate(examDate);

        scoreService.addScore(score);
        System.out.println("\n成绩添加成功！");
        pause();
    }

    private void updateScore() throws SMSException, DataFileCorruptedException {
        clearScreen();
        System.out.println("\n=== 修改成绩 ===");

        System.out.print("学生学号: ");
        String studentId = scanner.nextLine();

        System.out.print("课程ID: ");
        String courseId = scanner.nextLine();

        System.out.print("新成绩(0-100): ");
        double newScore = scanner.nextDouble();

        boolean success = scoreService.updateScore(studentId, courseId, newScore);
        if (success) {
            System.out.println("成绩修改成功!");
        } else {
            System.out.println("成绩记录不存在，修改失败!");
        }
        pause();
    }

    private void deleteScore() throws DataFileCorruptedException {
        clearScreen();
        System.out.println("\n=== 删除成绩 ===");

        System.out.print("学生学号: ");
        String studentId = scanner.nextLine();

        System.out.print("课程ID: ");
        String courseId = scanner.nextLine();

        boolean success = scoreService.deleteScore(studentId, courseId);
        if (success) {
            System.out.println("成绩删除成功!");
        } else {
            System.out.println("成绩记录不存在，删除失败!");
        }
        pause();
    }

    private void queryScore() throws DataFileCorruptedException {
        clearScreen();
        System.out.println("\n=== 查询成绩 ===");

        System.out.print("学生学号: ");
        String studentId = scanner.nextLine();

        System.out.print("课程ID: ");
        String courseId = scanner.nextLine();

        Score score = scoreService.getScore(studentId, courseId);
        if (score != null) {
            System.out.println("\n成绩信息:");
            System.out.println("学生学号: " + score.getStudentId());
            System.out.println("课程ID: " + score.getCourseId());
            System.out.println("成绩: " + score.getScore());
            System.out.println("考试日期: " + score.getExamDate());
        } else {
            System.out.println("成绩记录不存在!");
        }
        pause();
    }

    // ============ 报表统计操作方法 ============

    private void generateStudentReport() throws SMSException, DataFileCorruptedException {
        clearScreen();
        System.out.println("\n=== 学生成绩报表 ===");

        System.out.print("请输入学生学号: ");
        String studentId = scanner.nextLine();

        Map<String, Object> report = reportService.generateStudentReport(studentId);

        Student student = (Student) report.get("studentInfo");
        System.out.println("\n学生信息:");
        System.out.println("学号: " + student.getId());
        System.out.println("姓名: " + student.getName());
        System.out.println("班级: " + student.getClassName());

        System.out.println("\n成绩列表:");
        System.out.printf("%-10s %-20s %-5s%n", "课程ID", "课程名称", "成绩");
        System.out.println("----------------------------------");

        List<Score> scores = (List<Score>) report.get("scores");
        for (Score score : scores) {
            Course course = courseService.getCourse(score.getCourseId());
            System.out.printf("%-10s %-20s %-5.1f%n",
                    score.getCourseId(),
                    course != null ? course.getCourseName() : "未知课程",
                    score.getScore());
        }

        System.out.println("\n平均成绩: " + report.get("averageScore"));
        System.out.println("\n成绩分布:");
        Map<String, Long> distribution = (Map<String, Long>) report.get("scoreDistribution");
        distribution.forEach((k, v) -> System.out.println(k + ": " + v + "门"));

        pause();
    }

    private void generateClassReport() throws DataFileCorruptedException {
        clearScreen();
        System.out.println("\n=== 班级成绩报表 ===");

        System.out.print("请输入班级名称: ");
        String className = scanner.nextLine();

        Map<String, Object> report = reportService.generateClassReport(className);

        System.out.println("\n班级: " + className);
        System.out.println("学生人数: " + report.get("studentCount"));

        System.out.println("\n各科平均分:");
        System.out.printf("%-10s %-20s %-10s%n", "课程ID", "课程名称", "平均分");
        System.out.println("--------------------------------------");

        Map<String, Double> courseAverages = (Map<String, Double>) report.get("courseAverages");
        courseAverages.forEach((courseId, avg) -> {
            try {
                Course course = courseService.getCourse(courseId);
                System.out.printf("%-10s %-20s %-10.2f%n",
                        courseId,
                        course != null ? course.getCourseName() : "未知课程",
                        avg);
            } catch (DataFileCorruptedException e) {
                System.out.printf("%-10s %-20s %-10.2f%n",
                        courseId, "未知课程", avg);
            }
        });

        System.out.println("\n成绩分布:");
        Map<String, Long> distribution = (Map<String, Long>) report.get("scoreDistribution");
        distribution.forEach((k, v) -> System.out.println(k + ": " + v + "人次"));

        pause();
    }

    private void generateCourseReport() throws SMSException, DataFileCorruptedException {
        clearScreen();
        System.out.println("\n=== 课程成绩报表 ===");

        System.out.print("请输入课程ID: ");
        String courseId = scanner.nextLine();

        Map<String, Object> report = reportService.generateCourseReport(courseId);

        Course course = (Course) report.get("courseInfo");
        System.out.println("\n课程信息:");
        System.out.println("课程ID: " + course.getCourseId());
        System.out.println("课程名称: " + course.getCourseName());
        System.out.println("学分: " + course.getCredit());

        System.out.println("\n成绩统计:");
        System.out.println("平均分: " + report.get("averageScore"));
        System.out.println("最高分: " + report.get("maxScore"));
        System.out.println("最低分: " + report.get("minScore"));
        System.out.println("及格率: " + report.get("passRate"));

        System.out.println("\n成绩分布:");
        Map<String, Long> distribution = (Map<String, Long>) report.get("scoreDistribution");
        distribution.forEach((k, v) -> System.out.println(k + ": " + v + "人"));

        System.out.println("\n成绩前十名学生:");
        List<Map<String, Object>> topStudents = (List<Map<String, Object>>) report.get("topStudents");
        System.out.printf("%-10s %-10s %-5s%n", "学号", "姓名", "成绩");
        System.out.println("--------------------------");

        for (Map<String, Object> student : topStudents) {
            System.out.printf("%-10s %-10s %-5.1f%n",
                    student.get("studentId"),
                    student.get("studentName"),
                    student.get("score"));
        }

        pause();
    }

    private void generateSystemSummary() throws DataFileCorruptedException {
        clearScreen();
        System.out.println("\n=== 系统概要报表 ===");

        Map<String, Object> summary = reportService.generateSystemSummary();

        System.out.println("\n系统统计信息:");
        System.out.println("学生总数: " + summary.get("studentCount"));
        System.out.println("课程总数: " + summary.get("courseCount"));
        System.out.println("成绩记录总数: " + summary.get("scoreRecordCount"));

        System.out.println("\n班级分布:");
        Map<String, Long> classDistribution = (Map<String, Long>) summary.get("studentsByClass");
        classDistribution.forEach((className, count) ->
                System.out.println(className + ": " + count + "人"));

        System.out.println("\n全校成绩概况:");
        System.out.println("平均分: " + summary.get("overallAverage"));
        System.out.println("最高分: " + summary.get("highestScore"));
        System.out.println("最低分: " + summary.get("lowestScore"));

        System.out.println("\n成绩分布:");
        Map<String, Long> scoreDistribution = (Map<String, Long>) summary.get("scoreDistribution");
        scoreDistribution.forEach((k, v) -> System.out.println(k + ": " + v + "人次"));

        pause();
    }

    // ============ 辅助方法 ============

    private void displayLogo() {
        System.out.println("\n");
        System.out.println("  _____ _             _           _____ ___  ___ _____ ");
        System.out.println(" /  ___| |           | |         /  ___||  \\/  |/  ___|");
        System.out.println(" \\ `--.| |_ _   _  __| | ___ _ __\\ `--. | .  . |\\ `--. ");
        System.out.println("  `--. \\ __| | | |/ _` |/ _ \\ '__|`--. \\| |\\/| | `--. \\");
        System.out.println(" /\\__/ / |_| |_| | (_| |  __/ |  /\\__/ /| |  | |/\\__/ /");
        System.out.println(" \\____/ \\__|\\__,_|\\__,_|\\___|_|  \\____/ \\_|  |_/\\____/ ");
        System.out.println("                                                        ");
        System.out.println("========================================================");
    }

    private void clearScreen() {
        System.out.print("\033[H\033[2J");
        System.out.flush();
    }

    private void pause() {
        System.out.print("\n按回车键继续...");
        scanner.nextLine();
    }

    public int readIntInput() {
        while (!scanner.hasNextInt()) {
            System.out.println("请输入有效数字!");
            scanner.next();
        }
        int input = scanner.nextInt();
        scanner.nextLine(); // 清除换行符
        return input;
    }
}